#pragma once

#include <iostream>
#include <queue>
#include <pthread.h>

#define NUM 5

template <typename T>
class ThreadPool
{
  private:
    int thread_num;
    pthread_mutex_t lock;
    pthread_cond_t cond;
    std::queue<T> task_queue;
  public:
    ThreadPool(int _num = NUM): thread_num(_num)
    {
      pthread_mutex_init(&lock, nullptr);
      pthread_cond_init(&cond, nullptr);
    }

    void LockQueue()
    {
      pthread_mutex_lock(&lock);
    }

    void UnlockQueue()
    {
      pthread_mutex_unlock(&lock);
    }

    bool IsQueueEmpty()
    {
      return task_queue.size() == 0 ? true : false;
    }

    void Wakeup()  //唤醒线程
    {
      pthread_cond_signal(&cond);
    }

    void Wait()
    {
      pthread_cond_wait(&cond, &lock);
    }

    //static 静态方法 属于类 
    static void *Rountine(void *arg)
    {
      ThreadPool *self = (ThreadPool*)arg;
      while(true)
      {
        self->LockQueue();
        while(self->IsQueueEmpty())
        {
          //wait
          self->Wait();
        }
        T t;
        self->Pop(t);
        self->UnlockQueue();
        //处理任务TODO
        t.Run(); 
      }
    }

    void InitThreadPool()
    {
      pthread_t tid;
      for(int i = 0; i < thread_num; i++)
      {
          pthread_create(&tid, nullptr,  Rountine, this);
          //pthread_detach(tid);
      }
    }

    void Push(const T& in)
    {
      LockQueue();
      task_queue.push(in);  //任务
      UnlockQueue();
      Wakeup();
    }

    void Pop(T& out)
    {
      out = task_queue.front();
      task_queue.pop();
    }

    ~ThreadPool()
    {
      pthread_cond_destroy(&cond);
      pthread_mutex_destroy(&lock);
    }

};





//#pragma once 
//
//#include <iostream>
//#include <queue>
//#include <pthread.h>
//
//#define NUM 5
////你可不可以将线程池设计成为单例的！
//template <typename T>
//class ThreadPool{
//    private:
//        int thread_num;
//        std::queue<T> task_queue;
//        pthread_mutex_t lock;
//        pthread_cond_t cond;
//    public:
//        ThreadPool(int _num = NUM): thread_num(_num)
//        {
//            pthread_mutex_init(&lock, nullptr);
//            pthread_cond_init(&cond, nullptr);
//        }
//        void LockQueue()
//        {
//            pthread_mutex_lock(&lock);
//        }
//        void UnlockQueue()
//        {
//            pthread_mutex_unlock(&lock);
//        }
//        bool IsQueueEmpty()
//        {
//            return task_queue.size() == 0 ? true : false;
//        }
//        void Wait()
//        {
//            pthread_cond_wait(&cond, &lock);
//        }
//        void Wakeup()
//        {
//            pthread_cond_signal(&cond);
//        }
//        static void *Routine(void *arg)
//        {
//            pthread_detach(pthread_self());
//            ThreadPool *self = (ThreadPool*)arg;
//            while(true){
//                self->LockQueue();
//                while(self->IsQueueEmpty()){
//                    //wait
//                    self->Wait();
//                }
//                //任务队列一定有任务
//                T t;
//                self->Pop(t);
//                self->UnlockQueue();
//                //处理任务
//                t.Run();
//            }
//        }
//        void InitThreadPool()
//        {
//            pthread_t tid;
//            for(int i = 0; i < thread_num; i++){
//                pthread_create(&tid, nullptr, Routine, this);
//            }
//        }
//        void Push(const T& in)
//        {
//            LockQueue();
//            task_queue.push(in);
//            UnlockQueue();
//            Wakeup();
//        }
//        void Pop(T &out)
//        {
//            out = task_queue.front();
//            task_queue.pop();
//        }
//        ~ThreadPool()
//        {
//            pthread_cond_destroy(&cond);
//            pthread_mutex_destroy(&lock);
//        }
//};
//
